Skip to content

fix(install): set DM_DISABLE_UDEV=1 to prevent dm semaphore deadlock in container IPC namespace#2090

Merged
cgwalters merged 1 commit intobootc-dev:mainfrom
andrewdunndev:fix/luks-udev-cookie-deadlock
Apr 1, 2026
Merged

fix(install): set DM_DISABLE_UDEV=1 to prevent dm semaphore deadlock in container IPC namespace#2090
cgwalters merged 1 commit intobootc-dev:mainfrom
andrewdunndev:fix/luks-udev-cookie-deadlock

Conversation

@andrewdunndev
Copy link
Copy Markdown
Contributor

@andrewdunndev andrewdunndev commented Mar 24, 2026

Summary

Prevent the libdevmapper udev cookie semaphore deadlock that causes cryptsetup luksOpen/luksClose to hang inside containers with isolated IPC namespaces.

Root cause

When bootc install runs inside a container (the standard invocation), the container has its own IPC namespace by default. libdevmapper creates System V semaphores ("udev cookies") to synchronize with udevd, but udevd runs in the host IPC namespace and can't see the container's semaphores. The semop() call blocks forever.

Full analysis: #2089

Fix

Two changes, as suggested in review:

  1. --ipc=host in documented invocations (primary fix): Add --ipc=host to the podman run commands in bootc-install.md. This shares the host IPC namespace so libdevmapper's semaphores reach udevd. We already pass --pid=host and propagate /run, so --ipc=host is consistent.

  2. DM_DISABLE_UDEV=1 in global_init() (defense-in-depth): Set the env var early in process initialization, alongside the existing HOME workaround. This tells libdevmapper to skip udev synchronization entirely, catching cases where IPC sharing is not configured.

Fixes: #2089
Related: #421

@github-actions github-actions bot added the area/install Issues related to `bootc install` label Mar 24, 2026
@bootc-bot bootc-bot bot requested a review from jmarrero March 24, 2026 02:51
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses a deadlock issue with cryptsetup in containerized environments by setting the DM_DISABLE_UDEV=1 environment variable. The fix is well-explained and seems correct. My main feedback is to suggest a safer, unsafe-free way to set the environment variable for the child processes, which would improve the robustness of the implementation.

Copy link
Copy Markdown
Collaborator

@cgwalters cgwalters left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reopened and commented on #421 which is about the larger problem here - if we did that then there'd be no devmapper usage at all at installation time by bootc.

The container's default IPC namespace is isolated from the host.

I'd rather change that via changing our default install flow to use --ipc=host. We already propagate /run so this really makes sense.

As far as setenv - we already have global_init() that is the place for this.

@andrewdunndev andrewdunndev force-pushed the fix/luks-udev-cookie-deadlock branch from 812ff6a to 23d3fbe Compare March 25, 2026 16:52
@andrewdunndev andrewdunndev force-pushed the fix/luks-udev-cookie-deadlock branch from 23d3fbe to 3636925 Compare March 26, 2026 20:54
@github-actions github-actions bot added the area/documentation Updates to the documentation label Mar 26, 2026
@andrewdunndev
Copy link
Copy Markdown
Contributor Author

Reworked per your feedback. Added --ipc=host to the documented podman invocations as the primary fix, rebased on main, force-pushed.

I kept DM_DISABLE_UDEV=1 in global_init() as defense-in-depth for cases where someone runs the install without --ipc=host. But re-reading your review, I'm not sure that's what you wanted -- should I drop the setenv entirely and make this purely the docs change?

@andrewdunndev andrewdunndev force-pushed the fix/luks-udev-cookie-deadlock branch from 3636925 to f64cc0f Compare March 26, 2026 21:08
@andrewdunndev andrewdunndev force-pushed the fix/luks-udev-cookie-deadlock branch 2 times, most recently from 2ce942d to c5a751a Compare March 30, 2026 02:20
let pid1ipcns = std::fs::File::open("/proc/1/ns/ipc").context("open pid1 ipcns")?;
rustix::thread::move_into_link_name_space(
pid1ipcns.as_fd(),
Some(rustix::thread::LinkNameSpaceType::Ipc),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't compile, the enum member has a longer name

// cryptsetup operations to deadlock on semop(). The primary fix is to
// run the install container with --ipc=host; this is defense-in-depth
// for cases where the caller forgets that flag.
if let Ok(ns_pid1) = std::fs::read_link("/proc/1/ns/ipc") {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general rule avoid "error swallowing" - let's just propagate the error if we can't open. It shouldn't happen and if it does we want to know.

Inside a container with an isolated IPC namespace (the podman/docker
default), udevd on the host cannot see the container's semaphores,
causing cryptsetup luksOpen/luksClose to deadlock on semop().

The primary fix is adding --ipc=host to the documented podman
invocations. As defense-in-depth, call setns() into /proc/1/ns/ipc
at the very start of global_init() when the process is in a different
IPC namespace than pid 1, so that devmapper's udev synchronization
works correctly even if the caller omits --ipc=host.

Signed-off-by: Andrew Dunn <andrew@dunn.dev>
@andrewdunndev andrewdunndev force-pushed the fix/luks-udev-cookie-deadlock branch from c5a751a to eb332db Compare March 30, 2026 20:26
@andrewdunndev
Copy link
Copy Markdown
Contributor Author

CI failures are all quay.io/registry 502 Bad Gateway errors during container image pulls, not code issues. Should pass on re-run.

@cgwalters cgwalters enabled auto-merge (rebase) March 31, 2026 23:45
@cgwalters cgwalters merged commit ce44df9 into bootc-dev:main Apr 1, 2026
83 of 116 checks passed
@cgwalters
Copy link
Copy Markdown
Collaborator

Followup to regression from this in #2117

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/documentation Updates to the documentation area/install Issues related to `bootc install`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

install to-disk --block-setup tpm2-luks hangs: libdevmapper udev cookie semaphore deadlock in container IPC namespace

2 participants